/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_BINDER_H
#define ANDROID_BINDER_H

#include <binder/IBinder.h>

// ---------------------------------------------------------------------------
namespace android {

    class BBinder : public IBinder {
    public:
        BBinder();

        virtual const String16 &getInterfaceDescriptor() const;

        virtual bool isBinderAlive() const;

        virtual status_t pingBinder();

        virtual status_t dump(int fd, const Vector<String16> &args);

        virtual status_t transact(uint32_t code,
                                  const Parcel &data,
                                  Parcel *reply,
                                  uint32_t flags = 0);

        virtual status_t linkToDeath(const sp<DeathRecipient> &recipient,
                                     void *cookie = NULL,
                                     uint32_t flags = 0);

        virtual status_t unlinkToDeath(const wp<DeathRecipient> &recipient,
                                       void *cookie = NULL,
                                       uint32_t flags = 0,
                                       wp<DeathRecipient> *outRecipient = NULL);

        virtual void attachObject(const void *objectID,
                                  void *object,
                                  void *cleanupCookie,
                                  object_cleanup_func func);

        virtual void *findObject(const void *objectID) const;

        virtual void detachObject(const void *objectID);

        virtual BBinder *localBinder();

    protected:
        virtual             ~BBinder();

        virtual status_t onTransact(uint32_t code,
                                    const Parcel &data,
                                    Parcel *reply,
                                    uint32_t flags = 0);

    private:
        BBinder(const BBinder &o);

        BBinder &operator=(const BBinder &o);

        class Extras;

        Extras *mExtras;
        void *mReserved0;
    };

// ---------------------------------------------------------------------------

    class BpRefBase : public virtual RefBase {
    protected:
        BpRefBase(const sp<IBinder> &o);

        virtual                 ~BpRefBase();

        virtual void onFirstRef();

        virtual void onLastStrongRef(const void *id);

        virtual bool onIncStrongAttempted(uint32_t flags, const void *id);

        inline IBinder *remote() { return mRemote; }

        inline IBinder *remote() const { return mRemote; }

    private:
        BpRefBase(const BpRefBase &o);

        BpRefBase &operator=(const BpRefBase &o);

        IBinder *const mRemote;
        RefBase::weakref_type *mRefs;
        volatile int32_t mState;
    };

}; // namespace android

// ---------------------------------------------------------------------------

#endif // ANDROID_BINDER_H
